package org.bdware.doip.core.model.digitalObject;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 默认有一个特殊的element
 */
public class DoWithAPI extends DigitalObject{
    public DoWithAPI(String id, DoType type) {
        super(id, type);
    }

    public DoWithAPI(DigitalObject digitalObject){
        this(digitalObject.id, digitalObject.type);
        setAttributes(digitalObject.attributes);
        elements = digitalObject.elements;
    }

    public DigitalObject retrieveApiData(HashMap<String,String> parameters){
        if(elements == null || elements.size() == 0){
            return null;
        }
        for(Element apiElement : elements){
            if(apiElement.getData() != null){
                apiElement.dataString = new String(apiElement.getData());
            }
            if("api".equals(apiElement.type)) {
                //TODO 对于普通的用户不显示API信息，对于DO的创建者可以看到详细的attributes信息
                //apiElement.attributes = null;
                apiElement.dataString = getElementDataFromAPi(apiElement, parameters);
            }else{
                if(apiElement.attributes != null && apiElement.attributes.get("api") != null && apiElement.attributes.get("api").getAsBoolean()){
                    //api: true
                    //method: "get"
                    //url: "http://api.k780.com/?app=weather.today&weaId=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json"
                    apiElement.dataString = getElementDataFromAPi(apiElement, parameters);
                }
            }
        }
        return this;
    }


    public static String getElementDataFromAPi(Element apiElement, HashMap parameters){
        String type = apiElement.attributes.get("method").getAsString();
        String url = apiElement.attributes.get("url").getAsString();
        String result = "";
        if ("get".equals(type)) {
            result = sendGet(parameters, url);
        } else if ("post".equals(type)) {
            result = sendPost(parameters, url);
        }
        return result;
    }

    public static String sendGet(Map<String, String> reqMap, String url){
        String result = "fail to get result from API";
        CloseableHttpClient client = HttpClients.createDefault();
        StringBuilder sb = new StringBuilder();
        sb.append(url);
        if(reqMap != null &&  reqMap.size() > 0){
            sb.append("?");
            for(String key : reqMap.keySet()){
                sb.append(key+"="+reqMap.get(key)+"&&");
            }
        }
        url = sb.toString();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = client.execute(get);
            HttpEntity entity = response.getEntity();
            if(entity != null){
                result = EntityUtils.toString(entity);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static String sendPost(Map<String, String> reqMap, String url){
        String result;
        HttpPost post = new HttpPost(url);
        try{
            CloseableHttpClient httpClient = HttpClients.createDefault();
            List<BasicNameValuePair> params = new ArrayList<>();
            for(String keys:reqMap.keySet()){
                params.add(new BasicNameValuePair(keys,reqMap.get(keys)));
            }
            UrlEncodedFormEntity postForm = new UrlEncodedFormEntity(params,"utf-8");
            post.setEntity(postForm);
            HttpResponse response = httpClient.execute(post);

            InputStream in = response.getEntity().getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));
            StringBuilder strber= new StringBuilder();
            String line = null;
            while((line = br.readLine())!=null){
                strber.append(line+'\n');
            }
            br.close();
            in.close();
            result = strber.toString();
            if(response.getStatusLine().getStatusCode()!= HttpStatus.SC_OK){
                result = "服务器异常";
            }
        } catch (Exception e){
            System.out.println("请求异常");
            throw new RuntimeException(e);
        } finally{
            post.abort();
        }
        return result;
    }
}
